﻿using System;
using NUnit.Framework;

namespace UnitTests.NUnitDemo
{
    [TestFixture]
    public class Test1_SimpleTests  //<-- I know, I'm Breaking my casing rule... but it looks nicer in the solution explorer
    {
        /**********************************************************************
        ** 
        **  I love nunit, especially when you're using resharper. I won't get 
        **  into many of the details of unit testing here, there's plenty of 
        **  tutorials. I will demonstrate how I write tests and what I look for
        **  with asserts. 
        **  
        **  I'm totally with adding "_" between sentence fragments in test 
        **  names. Mainly because they're so long and descriptive. 
        **  
        **  As you'll notice, I follow the Arrange, Act, Assert model. I ALWAYS
        **  have those comments in my tests because I think it makes it very
        **  easy to see what the setup is, what the method under test is, and
        **  what we are trying to validate. 
        **  
        **  As much as I've tried, I just don't do Test Driven development. I do
        **  however writes tests as often as I can. I usually do this after I've
        **  completely writen a class. 
        **  
        **  There should always be only ONE method under test, per test. Just 
        **  think "There can be only one!" from Highlander. :D
        **  
        **  Tests are also a form of documentation of how a method can and should
        **  be used as well as what exceptions to expect.
        ** 
        **********************************************************************/

        protected class Person
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }

            public string FullName 
            { 
                get
                {
                    if (FirstName == null) throw new NullReferenceException("FirstName cannot be null!");
                    if (LastName == null) throw new NullReferenceException("LastName cannot be null!");
                    return String.Format("{0} {1}", FirstName, LastName);
                } 
            }
        }

        [Test]
        public void PersonFullName_ReturnsFirstNameAndLastNameSeperatedBySpace()
        {
            //Arrange
            var person = new Person
            {
                FirstName = "Jack",
                LastName = "Bauer"
            };

            //Act
            var fullName = person.FullName;

            //Assert
            Assert.That(fullName, Is.EqualTo("Jack Bauer"));
        }

        [Test]
        public void PersonFullName_WithNullFirstName_ThrowsNullReferenceException()
        {
            //Arrange
            var person = new Person
            {
                FirstName = null,
                LastName = "Bauer"
            };

            //Act & Assert
            Assert.Throws<NullReferenceException>(() => {
                var fullname = person.FullName;
            });
        }


    }
}
